
#include "CDSF_Timer.h"

#include "CDSF_Types.h"

#define kTimerTableSize	32

typedef struct {
	unsigned int countDown;
	SFTimerFunction function;
	void *data;
}SFTimerRecord;

typedef struct {
	unsigned int count;
	SFTimerRecord records[kTimerTableSize];
}SFTimerRecords;


static SFClockRate m_clockRate;
static SFTimerRecords m_timerTable;


SFCode SFTimerSchedule(SFTimerFunction func, SFTimeInterval time, void *data){
	SFTimerRecord *record;
	
	if((m_timerTable.count) >= kTimerTableSize){
		return SFCodeSpaceFullError;
	}
	
	record = &(m_timerTable.records[m_timerTable.count]);
	record->countDown = (int)(time * m_clockRate);
	record->function = func;
	record->data = data;
	(m_timerTable.count)++;

	return SFCodeOK;
}

static void fastRemoveRecord(unsigned int index){
	if((index+1) < (m_timerTable.count)){
		m_timerTable.records[index] = m_timerTable.records[(m_timerTable.count) - 1];
	}
	(m_timerTable.count)--;
}

SFCode SFTimerUnschedule(SFTimerFunction func){
	int i;

	for(i=0; i < m_timerTable.count; i++){
		if((m_timerTable.records[i].function) == func){
			fastRemoveRecord(i);
			i--;
		}
	}

	return SFCodeOK;
}

void SFTimerFire(){
	int i;
	
	for(i=0; i < (m_timerTable.count); i++){
		SFTimerRecord *record = &(m_timerTable.records[i]);
		
		if((record->countDown) == 0){
			record->function(record->data);
			fastRemoveRecord(i);
			i--;
		}
	}
}

SFCode SFTimerInit(SFClockRate rate){
	m_timerTable.count = 0;
	m_clockRate = rate;

	return SFCodeOK;
}

SFCode SFTimerDelegate(void){
	int i;

	for(i=0; i < (m_timerTable.count); i++){
		unsigned int *countDown = &(m_timerTable.records[i].countDown);
		*countDown = ((*countDown)>0)?((*countDown)-1):0;
	}

	return SFCodeOK;
}

